﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FuncWorks.XNA.XTiled;
using Microsoft.Xna.Framework;
using fess.RPG;
using Microsoft.Xna.Framework.Graphics;
using fess.Graphics;

namespace fess.Maps
{
  class CaveOut : GenericMap
  {
    List<ActionCharacter> caveGroup = new List<ActionCharacter>();
    ActionCharacter gelmir;
    List<Vector2> attackPoints;

    public CaveOut(FessGame game)
      : base(game, game.Content.Load<Map>("caveOut"))
    {
      drawObjects = true;

      var guyCoords = (from mo in map.ObjectLayers["exits"].MapObjects
                       where mo.Type == "place"
                       orderby int.Parse(mo.Name)
                       select mo.Bounds.Center.ToVector2()).ToList();

      var dirs = (from mo in map.ObjectLayers["exits"].MapObjects
                  where mo.Type == "direction"
                  orderby mo.Name
                  select mo.Bounds.Center.ToVector2()).ToList();

      attackPoints = (from mo in map.ObjectLayers["stuff"].MapObjects
                      where mo.Type == "attack"
                      select mo.Bounds.Center.ToVector2()).ToList();

      var guyDirs = new[] { 1, 2, 2, 3, 3, 4, 5 };

      var face = game.Content.Load<Texture2D>("chars/enemies/guy2-face");

      caveGroup.Add(gelmir = new ActionCharacter(new WalkingCharacter(new CharacterMovementSheet(game.Content.Load<Texture2D>("chars/enemies/guy2"))), 
        game.Content.Load<Texture2D>("chars/enemies/guy2-face"),
        "Гельмир", 3, 0, 4, 0.09));

      caveGroup.Add(new ActionCharacter(new WalkingCharacter(new CharacterMovementSheet(game.Content.Load<Texture2D>("chars/enemies/guy1"))),
        game.Content.Load<Texture2D>("chars/enemies/guy1-face"),
        "Орофер", 3, 3, 3, 0.1));

      caveGroup.Add(new ActionCharacter(new WalkingCharacter(new CharacterMovementSheet(game.Content.Load<Texture2D>("chars/enemies/girl1"))),
        game.Content.Load<Texture2D>("chars/enemies/girl1-face"),
        "Даэрула", 2, 3, 3, 0.11));

      caveGroup.Add(new ActionCharacter(new WalkingCharacter(new CharacterMovementSheet(game.Content.Load<Texture2D>("chars/enemies/guy3"))),
        game.Content.Load<Texture2D>("chars/enemies/guy3-face"),
        "Индодак", 3, 3, 3, 0.1));

      caveGroup.Add(new ActionCharacter(new WalkingCharacter(new CharacterMovementSheet(game.Content.Load<Texture2D>("chars/enemies/guy4"))),
        game.Content.Load<Texture2D>("chars/enemies/guy4-face"),
        "Миргор", 4, 0, 4, 0.09));

      caveGroup.Add(new ActionCharacter(new WalkingCharacter(new CharacterMovementSheet(game.Content.Load<Texture2D>("chars/enemies/guy5"))),
        game.Content.Load<Texture2D>("chars/enemies/guy5-face"),
        "Ценгон", 2, 4, 3, 0.12));

      caveGroup.Add(new ActionCharacter(new WalkingCharacter(new CharacterMovementSheet(game.Content.Load<Texture2D>("chars/enemies/girl2"))),
        game.Content.Load<Texture2D>("chars/enemies/girl2-face"),
        "Даэрула", 2, 3, 3, 0.09));

      for (int i = 0; i < caveGroup.Count; ++i)
      {
        AddCharacter(caveGroup[i], guyCoords[i], true, false);
        caveGroup[i].Character.Direction = dirs[guyDirs[i] - 1] - caveGroup[i].Character.Position;
        caveGroup[i].Damage += () =>
          {
            if (game.CaveQuest == FessGame.CaveQuestStatus.Began)
              game.CancelDialog();
          };

        caveGroup[i].Death += () =>
          {
            if (caveGroup.All(c => c.Dead))
            {
              game.fess.Say("Тут целое логово подпольных магов.\nНадо немедленно сообщить Тёмному.");
              game.CaveQuest = FessGame.CaveQuestStatus.Done;
            }
          };
      }

      gelmir.AddAI(new FollowAI(gelmir, game.fess));
    }

    public override void Activate()
    {
      game.fess.Character.Position = new Vector2(4, 32) * 32;
      base.Activate();
    }

    public override bool Update(GameTime gameTime)
    {
      if (!base.Update(gameTime))
        return false;

      if (game.CaveQuest == FessGame.CaveQuestStatus.Began && (game.fess.Character.Position - gelmir.Character.Position).Length() < 100 && 
        !game.IsInDialog)
      {
        gelmir.DropAIs();
        game.AddActivity(new Dialog(gelmir,
            () => { Attack(); },
            () => { InvokeDropMessages(); gelmir.Say("Я тебя предупреждал!"); Attack(); },
          new Dialog.Line(gelmir, "Поворачивай обратно, путник. Тебе здесь\nделать нечего."),
          new Dialog.Line(game.fess, "Меня послала Академия, чтобы выяснить,\nчто здесь происходит. Я не уйду, пока\nво всём не разберусь."),
          new Dialog.Line(gelmir, "Ого, парни, вы слышали? Академия про нас\nузнала. Придётся переезжать. А ты, приятель,\nостанешься здесь. Навсегда.")
          ));
      }

      return true;
    }

    private void Attack()
    {
      game.CaveQuest = FessGame.CaveQuestStatus.Fighting;

      caveGroup.Reverse();
      foreach (var c in caveGroup)
      {
        ChangeFaction(c, true);
        if (c.Mana == 0)
          c.AddAI(new MeleeAI(c, true));
        else
          c.AddAI(new MageAI(c, true, attackPoints));
      }
    }

    protected override bool ExitEngaged(MapObject exit)
    {
      if (exit.Name == "cave")
      {
        game.fess.Say("Что-то мне совершенно не хочется лезть\nв пещеру. Плохое предчувствие. Пусть\nстаршие маги наводят здесь порядок.");
      }
      else if (game.CaveQuest != FessGame.CaveQuestStatus.Fighting)
      {
        List<Answer> destinations = new List<Answer>();
        destinations.Add(new Answer("Домой", () => game.home.Activate()));
        destinations.Add(new Answer("Таверна", () => game.tavern.Activate()));
        if (game.CemeteryQuest != FessGame.CemeteryQuestStatus.Unknown)
          destinations.Add(new Answer("Кладбище", () => game.cemetery.Activate()));

        game.AddActivity(new Dialog(game.fess,
            () => { },
            () => { },
          new Dialog.Line(game.fess, "Пора возвращаться.", destinations.ToArray())));
      }
      return true;
    }
  }
}
